package com.central.apps.controller;

import com.alibaba.fastjson.JSONObject;
import com.central.app.common.util.DateUtils;
import com.central.app.service.HandlerService;
import com.central.apps.common.constant.ProjectPlanConstant;
import com.central.apps.common.util.ProjectPlanUtils;
import com.central.apps.entity.MpxjBean;
import com.central.apps.entity.TaskBean;
import com.central.apps.service.TaskService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 项目计划接口类
 *
 * @author 李大超
 * @date 2022/8/15
 */
@RestController
@Api(tags = "项目计划接口类")
@RequestMapping("/schedulePlan")
@Slf4j
public class SchedulePlanController {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private TaskService taskService;

    @GetMapping("/viewBaseLine")
    public String viewBaseLine(Integer proId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");

        MpxjBean mpxjBean = taskService.viewBaseLine(proId);

        if (mpxjBean != null) {
            json.put("mpxjBean", mpxjBean);
        }

        return json.toJSONString();
    }

    @GetMapping("/delTask")
    public String delTask(Integer proId, Integer taskId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");
        json.put("msg", " 删除成功!");

        // 删除任务
        String result = taskService.delTask(proId, taskId);

        if (StringUtils.isNotEmpty(result)) {
            json.put("code", "1");
            json.put("msg", result);
        }

        return json.toString();
    }

    @GetMapping("/startTask")
    public String startTask(Integer id) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");
        json.put("msg", "开工成功");

        Map<String, Object> map = handlerService.findOneBySql("select id, taskplanid, taskstatus, startTime from gq_mytask where status = '未开始' and id = " + id);

        if (map == null) {
            json.put("code", "1");
            json.put("msg", "任务已开工, 不能再进行开工!");
            return json.toString();
        }

        Integer taskPlanId = MapUtils.getInteger(map, "taskplanid");
        Map<String, Object> tpMap = new HashMap<>();
        tpMap.put("id", taskPlanId);

        String taskStatus = MapUtils.getString(map, "taskstatus");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date startTime = dateFormat.parse(MapUtils.getString(map, "startTime"));
        Date date = dateFormat.parse(dateFormat.format(new Date()));

        map.put("actstarttime", date);
        tpMap.put("actstarttime", date);
        map.put("status", "进行中");
        tpMap.put("status", "进行中");

        // 判断开工进度状态
        if (date.before(startTime)) {
            taskStatus = "提前开工";
        } else if (date.after(startTime)) {
            taskStatus = "延期开工";
        } else {
            taskStatus = "按期进行";
        }
        map.put("taskstatus", taskStatus);
        tpMap.put("taskstatus", taskStatus);

        // 更新任务状态
        handlerService.update("gq_mytask", map);
        // 更新计划状态
        handlerService.update("gq_scheduleplantask", tpMap);
        return json.toString();
    }

    @GetMapping("/endTask")
    public String endTask(Integer id) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");
        json.put("msg", "完工成功");

        Map<String, Object> map = handlerService.findOneBySql("select id, taskid, taskstatus, startTime, endTime from gq_mytask where status = '进行中' and id = " + id);

        if (map == null) {
            json.put("code", "1");
            json.put("msg", "任务未开工或已完工, 不能再进行完工!");
            return json.toString();
        }

        Integer taskid = MapUtils.getInteger(map, "taskid");
        Map<String, Object> tpMap = new HashMap<>();
        tpMap.put("id", taskid);

        String taskStatus = MapUtils.getString(map, "taskstatus");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date endTime = dateFormat.parse(MapUtils.getString(map, "endTime"));
        Date date = dateFormat.parse(dateFormat.format(new Date()));

        map.put("actendtime", date);
        tpMap.put("actendtime", date);
        map.put("status", "已完成");
        tpMap.put("status", "已完成");

        // 判断完工进度状态
        if (date.before(endTime)) {
            taskStatus = "提前完工";
        } else if (date.after(endTime)) {
            taskStatus = "延期完工";

            // 延期工时
            int delayDuration = DateUtils.daysBetween(date, endTime);
            map.put("delayduration", delayDuration);
            tpMap.put("delayduration", delayDuration);
        } else {
            taskStatus = "按期完工";
        }
        map.put("taskstatus", taskStatus);
        tpMap.put("taskstatus", taskStatus);

        // 计算实际工期
        long actDuration = DateUtils.daysBetweenExpWeekEnd(MapUtils.getString(map, "startTime"), MapUtils.getString(map, "endTime"));
        map.put("actduration", actDuration);
        tpMap.put("actduration", actDuration);

        // 更新任务状态
        handlerService.update("gq_mytask", map);
        // 更新计划状态
        handlerService.update("gq_scheduleplantask", tpMap);
        return json.toString();
    }

    @GetMapping("/viewTask")
    public String viewTask(Integer proId, Integer taskId) throws Exception {
        JSONObject json = new JSONObject();
        Map<String, Object> map = taskService.viewTask(proId, taskId);

        if(map != null){
            json.put("data", map);
        }

        return json.toJSONString();
    }

    @GetMapping("/viewPlan")
    public String viewPlan(Integer proId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");

        MpxjBean mpxjBean = taskService.viewPlan(proId);

        if (mpxjBean != null) {
            json.put("mpxjBean", mpxjBean);
        }

        return json.toJSONString();
    }

    @PostMapping("/modifyPlan")
    public String modifyPlan(@RequestBody MpxjBean mpxjBean, Integer proId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");
        json.put("msg", "保存成功");

        // TODO 校验里程碑逻辑
        mpxjBean = taskService.modifyPlan(mpxjBean, proId);

        if (mpxjBean != null) {
            json.put("mpxjBean", mpxjBean);
        }
        return json.toJSONString();
    }

    @PostMapping("/export")
    public void exportSchedulePlan(Integer id, String filePath) throws Exception {
        List<TaskBean> taskBeanList = new ArrayList<>();
        // 查询项目进度计划任务信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_scheduleplantask where scheduleplanid =" + id);

        if (CollectionUtils.isNotEmpty(taskList)) {
            for (Map<String, Object> taskMap : taskList) {
                Integer taskId = (Integer) taskMap.get("id");
                String name = (String) taskMap.get("name");
                Integer level = (Integer) taskMap.get("level");
                Integer manager = (Integer) taskMap.get("manager");
                Date startTime = (Date) taskMap.get("startTime");
                Date endTime = (Date) taskMap.get("endTime");
                Integer progress = (Integer) taskMap.get("progress");
                String assigns = (String) taskMap.get("assigns");
                String description = (String) taskMap.get("description");
                Integer predecessors = (Integer) taskMap.get("predecessors");
                Integer duration = (Integer) taskMap.get("duration");
                String durationTimeUnit = (String) taskMap.get("durationTimeUnit");
                Integer parentId = (Integer) taskMap.get("parentId");

                // 组织项目任务信息
                TaskBean taskBean = new TaskBean();
                taskBean.setId(taskId);
                taskBean.setRecordId(taskId.toString());
                taskBean.setUniqueId(taskId.toString());
                taskBean.setName(name);
                taskBean.setLevel(level);
                taskBean.setDuration((Number)duration);
                taskBean.setDurationTimeUnit(durationTimeUnit);
                taskBean.setDescription(description);
                taskBean.setParentId(parentId);
                taskBean.setStartTime(startTime);
                taskBean.setFinishTime(endTime);
                taskBean.setPercentageComplete((Number)progress);

                // 查询人员台账信息
                List<Map<String, Object>> personList = handlerService.findBySql("select name from gq_user where id =" + manager);
                // 组织负责人信息
                if (CollectionUtils.isNotEmpty(personList)) {
                    Map<String, Object> personMap = personList.get(0);
                    String personName = (String) personMap.get("name");
                    taskBean.setManager(personName);
                } else {
                    taskBean.setManager("");
                }

                // 查询前置任务信息
                List<Map<String, Object>> predecessorsList = handlerService.findBySql("select name from gq_scheduleplantask where id =" + predecessors);
                // 组织前置任务信息
                if (CollectionUtils.isNotEmpty(predecessorsList)) {
                    Map<String, Object> predecessorsMap = predecessorsList.get(0);
                    String predecessorsName = (String) predecessorsMap.get("name");
                    taskBean.setPredecessors(predecessorsName);
                }

                // 查询子任务信息
                List<Map<String, Object>> childTaskList = handlerService.findBySql("select name from gq_scheduleplantask where parentId =" + taskId);
                // 组织是否存在子任务信息
                taskBean.setHasChild(ProjectPlanConstant.HAS_CHILD);
                if (CollectionUtils.isNotEmpty(childTaskList)) {
                    taskBean.setHasChild(true);
                }

                // 查询分派人员信息
                if (StringUtils.isNotEmpty(assigns)) {
                    personList = handlerService.findBySql("select id, name, typework from gq_user where id in (" + assigns + ") order by id");
                    // 组织分派人员信息
                    if (CollectionUtils.isNotEmpty(personList)) {
                        List<String> resourceList = new ArrayList<>();
                        for (Map<String, Object> personMap : personList) {
                            String personName = (String) personMap.get("name");
                            resourceList.add(personName);
                        }

                        taskBean.setResources(resourceList);
                    }
                }

                taskBeanList.add(taskBean);
            }

            // 导出mpp文件
            ProjectPlanUtils.createMppFile(taskBeanList, filePath);
        }
    }

    @PostMapping("/import")
    public String importSchedulePlan(HttpServletRequest request, Integer projectId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("code", "0");
        json.put("msg", "导入成功");

        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        MultipartFile file = null;
        if (files.size()>0){
            file = files.get(0);
        }else {
            json.put("msg", "文件为空");
            return json.toString();
        }

        // 1.判断文件是否为空
        boolean empty = file.isEmpty();
        if(empty){
            json.put("msg", "文件为空");
            return json.toString();
        }

        // 2.判断文件名称是否为空
        String filename = file.getOriginalFilename();
        if (StringUtils.isEmpty(filename)) {
            json.put("msg", "文件名称为空");
            return json.toString();
        }

        // 3.判断文件类型是否正确
        Boolean bool = ProjectPlanUtils.checkFile(filename);
        if(!bool){
            json.put("msg", "文件类型不支持, 仅支持mpp/json文件类型");
            return json.toString();
        }

        return json.toString();
    }
}
